﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
using System.Threading;

namespace Infrastructure.Util
{
    public delegate void InterfaceUpdateHandler(string text, string portName);

    public class SerialPortOperator : Control
    {
        private SerialPort Sp = new SerialPort();
        ////private Dictionary<string, string> mapping = new Dictionary<string, string>
        ////{
        ////    {"1","1"},{"2","2"},{"3","3"},{"4","4"},{"5","5"},{"6","6"},{"7","7"},{"8","8"},{"9","9"},{"A","10"},{"B","11"},{"C","12"},{"D","13"},{"E","14"},
        ////    {"F","15"},{"G","16"},{"H","17"},{"I","18"},{"J","19"},{"K","20"},{"L","21"},{"M","22"},{"N","23"},{"O","24"},{"P","25"},{"Q","26"},{"R","27"},
        ////    {"S","28"},{"T","29"},{"U","30"},{"V","31"},{"W","32"},{"X","33"},{"Y","34"},{"Z","35"},{"-","36"},{".","37"},{" ","38"},{"$","39"},{"/","40"},
        ////    {"+","41"},{"%","42"}
        ////};

        public InterfaceUpdateHandler InterfaceUpdateHandle;

        public SerialPortOperator()
        {

        }

        public SerialPortOperator(string portName, int baudRate)
        {
            this.InitPort(portName, baudRate);
        }

        /// <summary>
        /// Sp Data Received
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Sp.DataReceived -= new SerialDataReceivedEventHandler(Sp_DataReceived);

            byte[] readBuffer = new byte[Sp.ReadBufferSize];
            Sp.Read(readBuffer, 0, readBuffer.Length);

            // 不停顿连续扫描会有问题
            Thread.Sleep(500);

            string sn = Encoding.ASCII.GetString(readBuffer);

            // 扫描出来的数据回事这样的：31012341001G\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0...
            int index = sn.IndexOf("\0");
            sn = sn.Substring(0, index);

            sn = sn.Replace("\n", string.Empty);
            sn = sn.Replace("\r", string.Empty);

            ////// 根据条码校验位来检查条码是否正确
            ////if (CheckSN(sn))
            ////{
            if (InterfaceUpdateHandle != null)
            {
                this.Invoke(InterfaceUpdateHandle,
                            new string[] { sn, Sp.PortName });
            }
            ////}
            ////else
            ////{

            ////    ////MessageBox.Show("扫描的序列号不正确，请重新扫描。");
            ////}

            Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
        }

        ////private bool CheckSN(string sn)
        ////{
        ////    bool isSNValid = false;
        ////    string checkedStr = sn.Substring(0, sn.Length - 1);
        ////    string finalStr = checkedStr;
        ////    int bcc = 0;
        ////    for (int i = 0; i < checkedStr.Length; i++)
        ////    {
        ////        int val = 0;
        ////        string key = checkedStr[i].ToString();
        ////        if (mapping.ContainsKey(key)) val = int.Parse(mapping[key]);
        ////        bcc += val;
        ////    }
        ////    string value = (bcc % 43).ToString();
        ////    string concatValue = string.Empty;
        ////    if (mapping.ContainsValue(value)) concatValue = mapping.First(p => p.Value == value).Key;
        ////    finalStr = finalStr + concatValue;
        ////    isSNValid = sn == finalStr;
        ////    return isSNValid;
        ////}

        /// <summary>
        /// Init Port
        /// </summary>
        /// <param name="portName"></param>
        /// <param name="baudRate"></param>
        public void InitPort(string portName, int baudRate)
        {
            Sp.PortName = portName;
            Sp.BaudRate = baudRate;
            Sp.Parity = Parity.None;
            Sp.StopBits = StopBits.One;
            Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
            Sp.ReceivedBytesThreshold = 1;
            try
            {
                Sp.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show("端口" + portName + "打开失败！");
                throw ex;
            }
        }

        /// <summary>
        /// Close Port
        /// </summary>
        public void ClosePort()
        {
            Sp.Close();
        }
    }
}
